home *** CD-ROM | disk | FTP | other *** search
- #include "stddefs.h"
- #include <stdlib.h>
- #include <fstream.h>
- #include <string.h>
- #include "icon.h"
- #include "animap.h"
- #include "xlib.h"
- #include "actor.h"
-
- inline int rollover(int number, int limit)
- {
- int temp = number % limit;
- temp += (temp < 0) ? limit : 0;
- return temp;
- // return number & (limit-1);
- }
-
- void animapSquare::display(int x, int y, word pageBase, int squareWidth)
- {
- draw(x, y, pageBase);
- if (nextActor)
- drawActors(x + thisFrame->picture.width - squareWidth,
- y + thisFrame->picture.height - squareWidth, pageBase);
- }
-
- void animapSquare::drawActors(int x, int y, word pageBase)
- {
- animactor * this_actor = nextActor;
- while (this_actor != NULL)
- {
- this_actor->draw(x - this_actor->thisFrame->picture.width + this_actor->squareX,
- y - this_actor->thisFrame->picture.height + this_actor->squareY, pageBase);
- this_actor = this_actor->nextActor;
- }
- }
-
- void animapSquare::advance(void)
- #define MAXINASQUARE 20
- {
- static animactor * voodooActors[MAXINASQUARE];
- animslave::advance();
- animactor ** voodooCounter = &voodooActors[0];
- animactor * this_actor = nextActor;
- while (this_actor != NULL)
- {
- *(voodooCounter++) = this_actor;
- this_actor = this_actor->nextActor;
- }
- *voodooCounter = NULL;
- voodooCounter = &voodooActors[0];
- while (*voodooCounter != NULL)
- {
- (*voodooCounter)->advance();
- ++voodooCounter;
- }
- }
-
- void * animap::isInSquare(int x, int y, byte searchIdentity)
- {
- x %= (int)(width);
- y %= (int)(height);
- x += (x < 0) ? width : 0;
- y += (y < 0) ? height : 0;
- animactor * this_actor = mapData[x][y].nextActor;
- while (this_actor != NULL)
- {
- if (this_actor->myIdentity == searchIdentity)
- return(this_actor);
- this_actor = this_actor->nextActor;
- }
- return NULL;
- }
-
-
- animap::animap(int inumIcons, int sqwidth, int iwidth, int iheight)
- {
- typedef animapSquare * mapptr;
- numIcons = inumIcons;
- width = iwidth;
- height = iheight;
- squareWidth = sqwidth;
- mapData = new mapptr[width];
- for(int widthCounter = 0; widthCounter < width; ++widthCounter)
- {
- mapData[widthCounter] = new animapSquare[height];
- }
- iconTable = new animicon[numIcons];
- iconNames = new fileNameString[numIcons];
- for (int iconCounter = 0; iconCounter < numIcons; ++iconCounter)
- {
- iconTable[iconCounter].firstFrame =
- iconTable[iconCounter].lastFrame =
- iconTable[iconCounter].thisFrame = NULL;
- strcpy(iconNames[iconCounter], "");
- }
- }
-
- animap::~animap()
- {
- for (int widthCounter = 0; widthCounter < width; ++widthCounter)
- delete mapData[widthCounter];
- delete mapData;
- for(widthCounter = 0; widthCounter < numIcons; ++widthCounter)
- {
- iconTable[widthCounter].animicon::~animicon();
- }
- delete iconTable;
- delete iconNames;
- };
-
- animap::animap(char * filename, yakLib * myYakLib)
- {
- int inumIcons, sqwidth, iwidth, iheight;
- ifstream infile(filename, ios::in | ios::binary);
- if (!infile) return;
- infile >> inumIcons >> sqwidth >> iwidth >> iheight;
- typedef animapSquare * mapptr;
- numIcons = inumIcons;
- width = iwidth;
- height = iheight;
- squareWidth = sqwidth;
- mapData = new mapptr[width];
- for(int widthCounter = 0; widthCounter < width; ++widthCounter)
- {
- mapData[widthCounter] = new animapSquare[height];
- }
- iconTable = new animicon[numIcons];
- iconNames = new fileNameString[numIcons];
- for (int iconCounter = 0; iconCounter < numIcons; ++iconCounter)
- {
- iconTable[iconCounter].firstFrame =
- iconTable[iconCounter].lastFrame =
- iconTable[iconCounter].thisFrame = NULL;
- strcpy(iconNames[iconCounter], "");
- }
- for (int counter = 0; counter < numIcons; ++counter)
- {
- infile >> iconNames[counter];
- loadIcon(counter, iconNames[counter], myYakLib);
- }
- for (word heightCounter = 0; heightCounter < height; ++heightCounter)
- {
- for (word widthCounter = 0; widthCounter < width; ++widthCounter)
- {
- infile >> mapData[widthCounter][heightCounter].myIconNumber;
- setSquare(widthCounter, heightCounter, mapData[widthCounter][heightCounter].myIconNumber);
- }
- }
- infile.close();
- }
-
-
- void animap::reset()
- {
- for (int widthCounter = 0; widthCounter < width; ++widthCounter)
- for (int heightCounter = 0; heightCounter < height; ++heightCounter)
- setSquare(widthCounter, heightCounter, mapData[widthCounter][heightCounter].myIconNumber);
- }
-
- void animap::setSquare(word x, word y, byte icon_number)
- {
- mapData[x][y].myIconNumber = icon_number;
- mapData[x][y].myTerrainType = icon_number;
- mapData[x][y].thisFrame = iconTable[icon_number].firstFrame;
- }
-
- void animap::save(char * filename)
- {
- ofstream outfile(filename, ios::in | ios::binary);
- if (!outfile) return;
- outfile << numIcons << '\n' << (int)squareWidth << '\n' << width << '\n' << height << '\n';
- for (int counter = 0; counter < numIcons; ++counter)
- outfile << iconNames[counter] << '\n';
- for (word heightCounter = 0; heightCounter < height; ++heightCounter)
- {
- for (word widthCounter = 0; widthCounter < width; ++widthCounter)
- {
- outfile << mapData[widthCounter][heightCounter].myIconNumber;
- }
- }
- outfile.close();
- }
-
- void animap::loadIcon(int position, char * filename, yakLib * myYakLib)
- {
- iconTable[position].addAll(filename, icon::fast, myYakLib);
- strcpy(iconNames[position], filename);
- }
-
- void animap::load(char * filename)
- {
- ifstream infile(filename, ios::in | ios::binary);
- if (!infile) return;
- infile >> numIcons >> squareWidth >> width >> height;
- for (int counter = 0; counter < numIcons; ++counter)
- {
- infile >> iconNames[counter];
- loadIcon(counter, iconNames[counter]);
- }
- for (word heightCounter = 0; heightCounter < height; ++heightCounter)
- {
- for (word widthCounter = 0; widthCounter < width; ++widthCounter)
- {
- infile >> mapData[widthCounter][heightCounter].myIconNumber;
- setSquare(widthCounter, heightCounter, mapData[widthCounter][heightCounter].myIconNumber);
- }
- }
- infile.close();
- }
-
-
- void animap::draw(int centerx, int centery, int screenx, int screeny, int radx, int rady, word offset)
- {
- int heightCounter, widthCounter, x, y;
- for (heightCounter = -rady; heightCounter <= rady; ++heightCounter)
- {
- for (widthCounter = -radx; widthCounter <= radx; ++widthCounter)
- {
- x = (centerx + widthCounter) % (int)(width);
- y = (centery + heightCounter) % (int)(height);
- x += (x < 0) ? width : 0;
- y += (y < 0) ? height : 0;
- mapData[x][y].display(screenx + squareWidth*widthCounter - mapData[x][y].thisFrame->picture.width,
- screeny + squareWidth*heightCounter - mapData[x][y].thisFrame->picture.height, offset, squareWidth);
- }
- }
- lastMapX = centerx-radx;
- lastMapY = centery-rady;
- lastScreenX = screenx - squareWidth * radx;
- lastScreenY = screeny - squareWidth * rady;
- lastDrawWidth = 2*radx+1;
- lastDrawHeight = 2*rady+1;
- }
-
- void animap::drawXY(int left, int top, int screenLeft, int screenTop, int drawWidth, int drawHeight, word offset)
- {
- int heightCounter, widthCounter, x, y;
- for (heightCounter = 0; heightCounter < drawHeight; ++heightCounter)
- {
- for (widthCounter = 0; widthCounter < drawWidth; ++widthCounter)
- {
- x = rollover(left + widthCounter, width);
- y = rollover(top + heightCounter, height);
- mapData[x][y].display(screenLeft + squareWidth*widthCounter - mapData[x][y].thisFrame->picture.width,
- screenTop + squareWidth*heightCounter - mapData[x][y].thisFrame->picture.height, offset, squareWidth);
- }
- }
- lastMapX = left;
- lastMapY = top;
- lastScreenX = screenLeft;
- lastScreenY = screenTop;
- lastDrawWidth = drawWidth;
- lastDrawHeight = drawHeight;
- }
-
- int max(int val1, int val2) {return((val1 > val2) ? val1 : val2);};
-
- void animap::advance()
- {
- int heightCounter, widthCounter, x, y;
- for (heightCounter = 0; heightCounter < height; ++heightCounter)
- for (widthCounter = 0; widthCounter < width; ++widthCounter)
- mapData[widthCounter][heightCounter].advance();
- }
-
-
- void animap::show(int centerx, int centery, int screenx, int screeny, int radx, int rady, word offset)
- {
- draw(centerx, centery, screenx, screeny, radx, rady, offset);
- advance();
- }
-
- void animap::showXY(int left, int top, int screenLeft, int screenTop, int width, int height, word offset)
- {
- drawXY(left, top, screenLeft, screenTop, width, height, offset);
- advance();
- }
-
- void animap::smartRefresh(int left, int top, word offset)
- {
- int heightCounter, widthCounter, x, y, oldX, oldY;
- int xCounter, yCounter;
- for (heightCounter = 0; heightCounter < lastDrawHeight; ++heightCounter)
- for (widthCounter = 0; widthCounter < lastDrawWidth; ++widthCounter)
- {
- x = rollover(left + widthCounter, width);
- y = rollover(top + heightCounter, height);
- oldX = rollover(lastMapX + widthCounter, width);
- oldY = rollover(lastMapY + heightCounter, height);
- mapData[x][y].refresh = (mapData[x][y].refresh == 3) ? 2 : ((mapData[x][y].refresh == 2) ? 1 : 0);
- if (mapData[x][y].thisFrame != mapData[oldX][oldY].thisFrame->nextFrame)
- mapData[x][y].refresh = 1;
- if (mapData[x][y].nextActor || mapData[oldX][oldY].nextActor)
- {
- mapData[x][y].refresh=1;
- mapData[rollover(x-1, width)][y].refresh =1;
- mapData[x][rollover(y-1, height)].refresh =1;
- mapData[rollover(x-1,width)][rollover(y-1,height)].refresh =1;
- }
- }
- for (heightCounter = 0; heightCounter < lastDrawHeight; ++heightCounter)
- {
- for (widthCounter = 0; widthCounter < lastDrawWidth; ++widthCounter)
- {
- x = rollover(left + widthCounter, width);
- y = rollover(top + heightCounter, height);
- oldX = rollover(lastMapX + widthCounter, width);
- oldY = rollover(lastMapY + heightCounter, height);
- if (mapData[x][y].refresh)
- mapData[x][y].display(lastScreenX + squareWidth*widthCounter - mapData[x][y].thisFrame->picture.width,
- lastScreenY + squareWidth*heightCounter - mapData[x][y].thisFrame->picture.height, offset, squareWidth);
- }
- }
- lastMapX = left;
- lastMapY = top;
- }
-
- void animap::randomize()
- {
- for (int heightCounter = 0; heightCounter < height; ++heightCounter)
- for (int widthCounter = 0; widthCounter < width; ++widthCounter)
- setSquare(widthCounter, heightCounter, random(numIcons));
- }